package com.undsf.crawler;

import com.undsf.utils.Pair;
import com.undsf.utils.PairList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * Created by Arathi on 2015/04/10.
 */
public class UndHttpClient {
    public static UndHttpClient instance = null;
    public static final String DEFAULT_PROXY_IP = "10.1.3.5";
    public static final int DEFAULT_PROXY_PORT = 809;

    protected CloseableHttpClient client;
    protected HttpHost proxy = null;
    protected RequestConfig config = null;

    public static UndHttpClient getInstance() {
        if (instance == null){
            instance = new UndHttpClient();
        }
        return instance;
    }

    public static void initInstance(){
        //Configure conf = Configure.getInstance();
        //instance = new KanHttpClient(conf.isUseProxy());
        instance = new UndHttpClient();
    }

    public static void initInstance(boolean useProxy){
        instance = new UndHttpClient(useProxy);
    }

    public static void initInstance(String proxyIp, int proxyPort){
        instance = new UndHttpClient(proxyIp, proxyPort);
    }

    public UndHttpClient(){
        initClient();
    }

    public UndHttpClient(boolean useProxy){
        initClient();
        if (useProxy){
            initProxy(DEFAULT_PROXY_IP, DEFAULT_PROXY_PORT);
        }
    }

    public UndHttpClient(String proxyIp, int proxyPort){
        initClient();
        initProxy(proxyIp, proxyPort);
    }

    public void initClient(){
        client = HttpClients.createDefault();
    }

    public void initProxy(String proxyIp, int proxyPort){
        proxy = new HttpHost(proxyIp, proxyPort, "http");
        config = RequestConfig.custom().setProxy(proxy).build();
    }

    public String getRequest(String url) throws IOException{
        String html = "";
        CloseableHttpResponse response = null;
        try{
            HttpGet request = new HttpGet(url);
            if (proxy!=null && config!=null) request.setConfig(config);
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
                throw new IOException("获取到错误的状态码");
            }
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                throw new IOException("无法获取到Entity");
            }
            html = EntityUtils.toString(entity);
        }
        catch (IOException e){
            throw e;
        }
        finally {
            if (response!=null){
                response.close();
            }
        }
        return html;
    }

    public String getRequest(String url, PairList<String,String> params) throws IOException{
        String urlWithParam = url+"?";
        boolean firstParamFlag = true;
        for (Pair<String,String> param : params){
            if (!firstParamFlag){
                urlWithParam += "&";
            }
            else{
                firstParamFlag = false;
            }
            String key = param.getKey();
            String value = param.getValue();
            urlWithParam += key+"="+value;
        }
        return getRequest(urlWithParam);
    }

    public String postRequest(String url, Map<String, String> params) throws IOException{
        String html = "";
        CloseableHttpResponse response = null;
        try{
            HttpPost request = new HttpPost(url);
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            //nvps.add(new BasicNameValuePair("ismobile", "0")); //detailid
            //组装nvps
            Set<String> paramKeys = params.keySet();
            for (String key : paramKeys){
                nvps.add(new BasicNameValuePair(key, params.get(key)));
            }
            try {
                request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (proxy!=null && config!=null) request.setConfig(config);
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
                throw new IOException("获取到错误的状态码");
            }
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                throw new IOException("无法获取到Entity");
            }
            html = EntityUtils.toString(entity);
            response.close();
        }
        catch (IOException e){
            throw e;
        }
        finally {
            if (response!=null){
                response.close();
            }
        }
        return html;
    }

    public boolean download(String path, String url, boolean overwrite) throws IOException{
        CloseableHttpResponse response = null;
        try{
            int indexOfSlash = url.lastIndexOf('/');
            String fileName = url;
            if (indexOfSlash>=0){
                fileName = url.substring(indexOfSlash);
            }
            String fileFullPath = "";
            //建立目录
            File dir = new File(path);
            if (dir.exists()){
                if (dir.isDirectory()){
                    fileFullPath = path + fileName;
                }
                else{
                    if (overwrite == false){
                        return false;
                    }
                    fileFullPath = path;
                }
            }
            else {
                //创建目录
                if ( dir.mkdirs()==false ){
                    return false;
                }
                fileFullPath = path + fileName;
            }
            HttpGet request = new HttpGet(url);
            if (proxy!=null && config!=null) request.setConfig(config);
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
                throw new IOException("获取到错误的状态码");
            }
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                throw new IOException("无法获取到Entity");
            }
            FileOutputStream fos = new FileOutputStream(fileFullPath);
            entity.writeTo(fos);
            fos.close();
            //html = EntityUtils.toString(entity);
        }
        catch (IOException e){
            throw e;
        }
        finally {
            if (response!=null){
                response.close();
            }
        }
        return false;
    }

    public boolean close(){
        try{
            client.close();
            return true;
        }
        catch (IOException e){
            e.printStackTrace();
            return false;
        }
    }

    public static void main(String[] args) {
        UndHttpClient khClient = new UndHttpClient(false);
        //Map<String, String> params = new HashMap<String, String>();
        //params.put("ismobile", "0");
        try{
            String html = khClient.getRequest("http://whois.chinaz.com/acigh.com");
            System.out.println(html);
        }
        catch (IOException e){
            e.printStackTrace();
        }
        khClient.close();
    }

}
